package com.sanyou.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sanyou.mapper.MenuMapper;
import com.sanyou.mapper.RoleMenuMapper;
import com.sanyou.pojo.Menu;
import com.sanyou.pojo.RoleMenu;
import com.sanyou.pojo.vo.MenuVo;
import com.sanyou.service.MenuService;
import com.sanyou.utils.PagedResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class MenuServiceImpl implements MenuService {

    @Autowired
    private MenuMapper menuMapper;

    @Autowired
    private RoleMenuMapper roleMenuMapper;

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<MenuVo> getMenuItems(String userId) {

        List<Menu> menus;

        if(StringUtils.isBlank(userId))
            menus = menuMapper.selectAll();
        else
            menus = menuMapper.getMenuItems(userId);

        if(menus == null || menus.size() == 0)
            return new ArrayList<>();

        List<Menu> parentMenus = menus.stream().filter(t -> t.getParent() == 1).sorted(Comparator.comparing(Menu::getSort)).collect(Collectors.toList());
        if(parentMenus == null || parentMenus.size() == 0)
            return new ArrayList<>();

        List<MenuVo> resultMenu = new ArrayList<>();
        for (Menu parentMenu : parentMenus) {
            MenuVo menuVo = new MenuVo();
            BeanUtils.copyProperties(parentMenu,menuVo);
            List<Menu> collect = menus.stream().filter(t -> t.getParentId() == parentMenu.getId()).collect(Collectors.toList());
            if(collect != null && collect.size() > 0){
                List<MenuVo> childMenu = new ArrayList<>();
                for (Menu menu : collect) {
                    MenuVo childMenuVo = new MenuVo();
                    BeanUtils.copyProperties(menu,childMenuVo);
                    childMenu.add(childMenuVo);
                }
                menuVo.setChildren(childMenu);
            }
            resultMenu.add(menuVo);
        }

        return resultMenu;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<Menu> getParentMenu() {
        Example example = new Example(Menu.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("parent",1);

        return menuMapper.selectByExample(example);
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public PagedResult query(String query, Integer page, Integer pageSize) {
        PageHelper.startPage(page,pageSize);
        List<MenuVo> menuVoList = menuMapper.query(query);

        for (MenuVo menuVo : menuVoList) {
            Example example = new Example(Menu.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("parentId",menuVo.getId());
            List<Menu> menuList = menuMapper.selectByExample(example);

            if(menuList != null && menuList.size() > 0){
                menuVo.setHasChildren(true);
            }else{
                menuVo.setHasChildren(false);
            }
        }

        PageInfo<MenuVo> pageList = new PageInfo<>(menuVoList);

        PagedResult pagedResult = new PagedResult();
        pagedResult.setPage(page);
        pagedResult.setTotal(pageList.getPages());
        pagedResult.setRows(menuVoList);
        pagedResult.setRecords(pageList.getTotal());
        return pagedResult;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void addMenu(Menu menu) {
        List<MenuVo> menuVoList = menuMapper.query("");
        int order = menuVoList==null?1:menuVoList.size()+1;

        menu.setSort(order);
        menu.setCreatetime(new Date());
        menu.setType("ios-paper");

        menuMapper.insert(menu);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void addSubMenu(Menu menu) {
        Example example = new Example(Menu.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("parentId",menu.getParentId());
        List<Menu> menuList = menuMapper.selectByExample(example);

        int order = menuList==null?1:menuList.size()+1;
        menu.setType("ios-grid");
        menu.setSort(order);
        menu.setCreatetime(new Date());

        menuMapper.insert(menu);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void deleteMenu(Menu menu) {
        if(menu.getParent() == 1){
            Example example = new Example(Menu.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("parentId",menu.getId());
            menuMapper.deleteByExample(example);
        }
        menuMapper.deleteByPrimaryKey(menu.getId());
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void updateMenu(Menu updateMenu) {
        menuMapper.updateByPrimaryKeySelective(updateMenu);
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<Menu> querySubMenu(String parentId) {
        Example example = new Example(Menu.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("parentId",parentId);
        List<Menu> menuList = menuMapper.selectByExample(example);
        return menuList;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void assignMenu(List<Integer> menuIds, String roleId) {
        Example example = new Example(RoleMenu.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("roleId",roleId);
        roleMenuMapper.deleteByExample(example);

        RoleMenu homeMenu = new RoleMenu();
        homeMenu.setRoleId(roleId);
        Example example2 = new Example(Menu.class);
        Example.Criteria criteria2 = example2.createCriteria();
        criteria2.andEqualTo("name","home");
        List<Menu> menuList = menuMapper.selectByExample(example2);
        Menu menu = menuList.get(0);
        homeMenu.setMenuId(menu.getId());

        if(menuIds != null && menuIds.size() > 0){
            List<RoleMenu> roleMenus = new ArrayList<>();
            for (Integer menuId : menuIds) {
                RoleMenu roleMenu = new RoleMenu();
                roleMenu.setRoleId(roleId);
                roleMenu.setMenuId(menuId);
                roleMenus.add(roleMenu);
            }

            roleMenuMapper.insertList(roleMenus);

            List<Integer> collect = menuIds.stream().filter(t -> t.equals(homeMenu.getMenuId())).collect(Collectors.toList());
            if(collect == null || collect.size() == 0)
                roleMenuMapper.insert(homeMenu);

        }else{
            roleMenuMapper.insert(homeMenu);
        }
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<Integer> getRoleMenu(String roleId) {

        Example example = new Example(RoleMenu.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("roleId",roleId);
        List<RoleMenu> roleMenus = roleMenuMapper.selectByExample(example);

        if(roleMenus == null || roleMenus.size() == 0)
            return new ArrayList<>();

        return roleMenus.stream().map(t->t.getMenuId()).collect(Collectors.toList());
    }
}
